package com.bfxy.disruptor.quickstart;

import com.lmax.disruptor.BlockingWaitStrategy;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;

import java.nio.ByteBuffer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {


    public static void main(String[] args) {


        // 参数准备工作
        OrderEventFactory orderEventFactory = new OrderEventFactory();
        int ringBufferSize = 4;
        ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

        /**
         * 1 eventFactory: 消息(event)工厂对象
         * 2 ringBufferSize: 容器的长度
         * 3 executor: 线程池(建议使用自定义线程池) RejectedExecutionHandler
         * 4 ProducerType: 单生产者 还是 多生产者
         * 5 waitStrategy: 等待策略
         */
        //1. 实例化disruptor对象,disruptor是一个框架，里面是没有什么消费者与生产者的，这个需要后面进行设置
        Disruptor<OrderEvent> disruptor = new Disruptor<OrderEvent>(orderEventFactory,
                ringBufferSize,
                executor,
                ProducerType.SINGLE,
                new BlockingWaitStrategy());

        //2. 添加消费者的监听 (构建disruptor 与 消费者的一个关联关系)
        disruptor.handleEventsWith(new OrderEventHandler());

        //3. 启动disruptor
        disruptor.start();

        //4. 获取实际存储数据的容器: RingBuffer,disruptor从容器中获取数据
        RingBuffer<OrderEvent> ringBuffer = disruptor.getRingBuffer();

        // 生产者将产品生产至容器中，ringBuffer中去
        OrderEventProducer producer = new OrderEventProducer(ringBuffer);

        // 一个产品所分配的大小
        ByteBuffer bb = ByteBuffer.allocate(8);

        // 实际的生产
        for (long i = 0; i < 5; i++) {
            // 写入值
            bb.putLong(0, i);
            // 往生产者里放入数据
            producer.sendData(bb);
        }

        disruptor.shutdown();
        executor.shutdown();

    }
}
